package form
{
   import flash.events.*;
   import flash.display.*;
   import flash.geom.*;
   import flash.net.*;
   import flash.text.*;
   import flash.utils.*;
   import flash.ui.*;
   // adobe
   import com.adobe.images.*;
   // my lib
   import contrib.net.*;

   /**
    * @author   cjboy1984
    * 上傳照片的表格樣版
    */
   public class MyUploadPhotoForm extends MovieClip
   {
      // width, height (actually the mask)
      public var PHOTO_W:Number;
      public var PHOTO_H:Number;

      // fla
      public var tfPhoto:TextField; // 照片顯示路徑
      public var btnBrowse:MyButton; // 瀏覽按鈕
      public var mcUsrPhoto:MovieClip; // 存放照片的mc

      // file
      private var fileRef:FileReference = new FileReference();
      private var fileLdr:Loader = new Loader();
      private var photoContainer:Sprite = new Sprite();

      /* constructor */
      public function MyUploadPhotoForm()
      {
         photoContainer.buttonMode = true;

         addEventListener(Event.ADDED_TO_STAGE, onAdd);
         addEventListener(Event.REMOVED_FROM_STAGE, onRemove);
      }

      // ------------------ LINE -------------------

      // 重填
      public function refill():void
      {
         tfPhoto.text = '';

         fileRef.cancel();
         fileLdr.unload();

         for (var i:int = 0; i < photoContainer.numChildren; ++i)
         {
            photoContainer.removeChildAt(i);
         }
         photoContainer.x = photoContainer.y = 0;
      }

      // 檢查是否資料正確
      public function check():Boolean
      {
         if (photoContainer.numChildren < 1)
         {
            MyAlert.jsShow('您忘了上傳照片囉！');
            ret = false;
         }
         else
         {
            // 原圖縮放
            var org_WH_Rate:Number = fileLdr.content.width / fileLdr.content.height;
            var sr:Number = org_WH_Rate >= BUFF_WH_RATE ? BUFF_H / fileLdr.content.height : BUFF_W / fileLdr.content.width; // 考量了寬形圖還是窄形圖
            var newW:Number = fileLdr.content.width * sr;
            var newH:Number = fileLdr.content.height * sr;

            var matrix:Matrix = new Matrix();
            matrix.scale(sr, sr);
            var orgBmpData:BitmapData = new BitmapData(newW, newH);
            orgBmpData.draw(photoContainer, matrix);

            DEF.usrPhoto2 = orgBmpData;
            DEF.usrPhotoByteArray2 = new JPGEncoder(50).encode(DEF.usrPhoto2);

            // 裁圖製作，以縮放後的原圖為參考
            var photoAndContainerSizeRate:Number = PHOTO_W / photoContainer.width;
            var borderX:Number = photoContainer.x / photoAndContainerSizeRate;
            var borderY:Number = photoContainer.y / photoAndContainerSizeRate;
            var borderW:Number = newW * PHOTO_W / photoContainer.width;
            var borderH:Number = newH * PHOTO_H / photoContainer.height;

            matrix = new Matrix();
            matrix.translate(borderX, borderY);
            var cropBmpData:BitmapData = new BitmapData(borderW, borderH);
            cropBmpData.draw(orgBmpData, matrix);

            DEF.usrPhoto = cropBmpData;
            DEF.usrPhotoByteArray = new JPGEncoder(50).encode(DEF.usrPhoto);

            // 這裡要傳相框比例在原圖上的裁圖！
            //var orgW:Number = photoContainer.width / photoContainer.scaleX;
            //var orgH:Number = photoContainer.height / photoContainer.scaleY;
            //var borderX:Number = photoContainer.x / photoContainer.scaleX;
            //var borderY:Number = photoContainer.y / photoContainer.scaleY;
            //var borderW:Number = PHOTO_W / photoContainer.scaleX;
            //var borderH:Number = PHOTO_H / photoContainer.scaleY;
//
            //var cropBmpData:BitmapData = new BitmapData(borderW, borderH, false, 0xffffff);
            //cropBmpData.draw(photoContainer, new Matrix(1, 0, 0, 1, borderX, borderY), null, null, new Rectangle(0, 0, borderW, borderH));

            // crop-one
            //DEF.usrPhoto = cropBmpData;
            //DEF.usrPhotoByteArray = new JPGEncoder(50).encode(DEF.usrPhoto);

            // org-one
            //DEF.usrPhoto2 = new BitmapData(orgW, orgH).draw(photoContainer);
            //DEF.usrPhotoByteArray2 = new JPGEncoder(80).encode(DEF.usrPhoto2);

            // >test<
            //stage.addChild(new Bitmap(DEF.usrPhoto));

            return true;
         }
      }

      // ################ Protected ################

      // ################# Private #################

      private function onAdd(e:Event):void
      {
         // data
         PHOTO_W = mcUsrPhoto.width;
         PHOTO_H = mcUsrPhoto.height;

         // browse
         btnBrowse.onClick = function()
         {
            fileRef.browse( new Array( new FileFilter( "Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png" ) ) );
         }

         // file
         fileRef.addEventListener(Event.COMPLETE, onFileComplete);
         fileRef.addEventListener(Event.SELECT, onFileSelect);
         fileLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, onFileLoad);

         // photo (drag & zoom)
         mcUsrPhoto.addChild(photoContainer);
         mcUsrPhoto.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
         mcUsrPhoto.addEventListener(MouseEvent.MOUSE_WHEEL, onZoom);
      }

      private function onRemove(e:Event):void
      {
         fileRef.cancel();
         fileLdr.unload();

         fileRef.removeEventListener(Event.COMPLETE, onFileComplete);
         fileRef.removeEventListener(Event.SELECT, onFileSelect);
         fileLdr.contentLoaderInfo.removeEventListener(Event.COMPLETE, onFileLoad);

         // stop mouse-drage and then remove photo container
         photoContainer.stopDrag();
         mcUsrPhoto.removeChild(photoContainer);

         mcUsrPhoto.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
         mcUsrPhoto.removeEventListener(MouseEvent.MOUSE_WHEEL, onZoom);
         stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.removeEventListener(MouseEvent.ROLL_OUT, onStopDrag);
      }

      // ------------------ LINE -------------------

      // 檔案選取，本地端讀入
      private function onFileSelect(e:Event):void
      {
         //trace('onFileSelect');
         tfPhoto.text = fileRef.name;

         // load local file
         fileRef.load();
      }

      // 本地端開始讀
      private function onFileComplete(e:Event):void
      {
         //trace('onFileComplete');
         fileLdr.loadBytes(fileRef.data);
      }

      // 本地端讀完
      private function onFileLoad(e:Event):void
      {
         //trace('onFileLoad');
         for (var i:int = 0; i < photoContainer.numChildren; ++i)
         {
            photoContainer.removeChildAt(i);
         }

         // change focus
         //stage.focus = photoContainer;

         photoContainer.x = photoContainer.y = 0;
         photoContainer.addChild(fileLdr.content);

         // scale & put it center
         MyUtils.scaleToFillArea(photoContainer, PHOTO_W, PHOTO_H, 'proportionalOutside');
         photoContainer.x = (PHOTO_W - photoContainer.width) / 2;
         photoContainer.y = (PHOTO_H - photoContainer.height) / 2;
      }

      // ------------------ LINE -------------------

      private function onDown(e:MouseEvent):void
      {
         if (photoContainer.numChildren < 1) return;

         var offX:Number = PHOTO_W - photoContainer.width;
         var offY:Number = PHOTO_H - photoContainer.height;
         var rect:Rectangle = new Rectangle(offX, offY, Math.abs(offX), Math.abs(offY));

         photoContainer.startDrag(false, rect);
         stage.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.addEventListener(MouseEvent.ROLL_OUT, onStopDrag);
      }

      private function onStopDrag(e:MouseEvent):void
      {
         photoContainer.stopDrag();

         stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
         stage.removeEventListener(MouseEvent.ROLL_OUT, onStopDrag);
      }

      private function onZoom(e:MouseEvent):void
      {
         if (photoContainer.numChildren < 1) return;

         // avoid drag & zoom
         photoContainer.stopDrag();

         var orgW:Number = photoContainer.width / photoContainer.scaleX;
         var orgH:Number = photoContainer.height / photoContainer.scaleY;

         var scaleXY:Number = photoContainer.scaleX; // proportional x and y
         scaleXY += e.delta / Math.abs(e.delta) * 0.05 || 0; // edit scroll-speed here

         var newW:Number = orgW * scaleXY;
         var newH:Number = orgH * scaleXY;

         // limit width, height
         if (newW >= PHOTO_W && newH >= PHOTO_H)
         {
            // scale proportionally
            photoContainer.scaleX = photoContainer.scaleY = scaleXY;

            // Try to have the map zoom to the position at which the mouse is located. (localX, localY: The x/y at which the event occurred relative to the containing sprite.)
            var newX:Number = mcUsrPhoto.mouseX - e.localX * photoContainer.scaleX;
            var newY:Number = mcUsrPhoto.mouseY - e.localY * photoContainer.scaleY;

            // limit x, y
            if (newX + newW < PHOTO_W)
            {
               newX = PHOTO_W - newW;
            }
            else if(newX > 0)
            {
               newX = 0;
            }
            if (newY + newH < PHOTO_H)
            {
               newY = PHOTO_H - newH;
            }
            else if (newY > 0)
            {
               newY = 0;
            }

            photoContainer.x = newX;
            photoContainer.y = newY;
         }
      }

      // ------------------ LINE -------------------

   }

}